using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace Server
{
    public partial class MainForm : Form
    {
        private String password;
        private UInt16 port;
        private ChatDialog chatDialog;
        private ServerSocketClass socketCl;
        private Thread socketThread;

        private AutoResetEvent nextFrame;
        private bool paused;

        private char pauseKey;

        public MainForm()
        {
            InitializeComponent();
            socketCl = null;
            chatDialog = null;
            paused = false;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            ServerConfig conf = new ServerConfig();
            DialogResult res = conf.ShowDialog(this);
            switch (res)
            {
                case DialogResult.OK:
                    password = conf.Password;
                    port = conf.Port;
                    pauseKey = conf.PauseKey;
                    conf.Dispose();
                    ScreenChooser chooserDialog = new ScreenChooser();
                    DialogResult res2 = chooserDialog.ShowDialog(this);
                    if (res2 == DialogResult.OK)
                    {
                        bool windowCapture = chooserDialog.WindowMode;
                        IntPtr capturedWindow = IntPtr.Zero;
                        Rectangle screenRectangle = Rectangle.Empty;
                        if (windowCapture)
                            capturedWindow = chooserDialog.CapturedWindow;
                        else
                            screenRectangle = chooserDialog.CapturedRectangle;
                        nextFrame = new AutoResetEvent(false);
                        chooserDialog.Dispose();
                        chatDialog = new ChatDialog();

                        if(windowCapture)
                            socketCl = new ServerSocketClass(port, this, chatDialog, password, nextFrame, capturedWindow);
                        else
                            socketCl = new ServerSocketClass(port, this, chatDialog, password, nextFrame, screenRectangle);
                        socketThread = new Thread(new ThreadStart(socketCl.acceptConnections));
                        socketThread.Start();

                        timer1.Enabled = true;
                        chatDialog.Show();
                    }
                    else
                    {
                        chooserDialog.Dispose();
                        Environment.Exit(0);
                    }
                    break;
                default:
                    conf.Dispose();
                    Environment.Exit(0);
                    break;
            }
        }

        public void CloseMe()
        {
            this.Close();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (chatDialog != null)
            {
                chatDialog.ReleaseClipboard();
                chatDialog.Close();
                chatDialog.Dispose();
            }
            if (socketCl != null)
            {
                socketCl.requestClose();
            }
        }

        public void UpdateFrame(Bitmap bmp, int x, int y)
        {
            if (pictureBox1.Image != null)
            {
                using (Graphics gfx = Graphics.FromImage(pictureBox1.Image))
                {
                    gfx.DrawImage(bmp, x, y);
                }
                pictureBox1.Invalidate();
            }
        }

        public void DrawRectangle(Rectangle r)
        {
            if (pictureBox1.Image != null)
            {
                if (r.Width > 0 && r.Height > 0)
                {
                    using (Graphics gfx = Graphics.FromImage(pictureBox1.Image))
                    {
                        gfx.DrawRectangle(Pens.Lime, r);
                        using (SolidBrush brush = new SolidBrush(Color.FromArgb(100, Color.Lime)))
                        {
                            gfx.FillRectangle(brush, r);
                        }
                    }
                    pictureBox1.Invalidate();
                }
            }
        }

        public void setImage(Bitmap bmp)
        {
            if (bmp != null)
            {
                bool translate = false;

                float xTranslate = 0.0F;
                float yTranslate = 0.0F;

                Size modifiedSize = bmp.Size;

                if (modifiedSize.Width < pictureBox1.MinimumSize.Width)
                {
                    xTranslate = (pictureBox1.MinimumSize.Width - modifiedSize.Width) / 2;
                    modifiedSize.Width = pictureBox1.MinimumSize.Width;
                    translate = true;
                }
                if (modifiedSize.Height < pictureBox1.MinimumSize.Height)
                {
                    yTranslate = (pictureBox1.MinimumSize.Height - modifiedSize.Height) / 2;
                    modifiedSize.Height = pictureBox1.MinimumSize.Height;
                    translate = true;
                }

                if (translate)
                {
                    Bitmap modified = new Bitmap(modifiedSize.Width, modifiedSize.Height);
                    using (Graphics gfx = Graphics.FromImage(modified))
                    {
                        gfx.TranslateTransform(xTranslate, yTranslate);
                        gfx.DrawImage(bmp, 0, 0);
                    }
                    if (pictureBox1.Image != null)
                        pictureBox1.Image.Dispose();
                    pictureBox1.Image = modified;
                }
                else
                {
                    if (pictureBox1.Image != null)
                        pictureBox1.Image.Dispose();
                    pictureBox1.Image = new Bitmap(bmp);
                }
            }
        }

        private void pictureBox1_Resize(object sender, EventArgs e)
        {
            this.ClientSize = new Size(pictureBox1.Width + 2 * pictureBox1.Left, pictureBox1.Height + 2 * pictureBox1.Top);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //pictureBox1.Invalidate();
            nextFrame.Set();
        }

        private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == pauseKey)
            {
                if (!paused)
                {
                    paused = true;
                    socketCl.pauseVideoTransmission(true);
                }
                else
                {
                    socketCl.resumeVideoTransmission();
                    paused = false;
                }

            }
        }
    }
}